﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ModelUML
{
    [Serializable]
    public class KontenerUML : ElementUML
    {
        KolekcjaUML elementy;        
        public KontenerUML()
        {
            elementy = new KolekcjaUML();
        }
        public KolekcjaUML Elementy
        {
            get
            {
                return elementy;
            }
        }
        public AktorUML DodajAktora()
        {
            AktorUML aktor = new AktorUML();
            elementy.Dodaj(aktor);
            return aktor;
        }

        public NotatkaUML DodajNowaNotatke(String nazwa)
        {
            NotatkaUML n = base.DodajNotatke(nazwa);
            elementy.Dodaj(n);
            return n;
        }
        
        public PakietUML DodajPakiet(String nazwa)
        {
            PakietUML pakiet = new PakietUML();
            pakiet.Nazwa = nazwa;
            elementy.Dodaj(pakiet);            
            return pakiet;
        }
        public KlasaUML DodajKlase(String nazwa)
        {
            KlasaUML klasa = new KlasaUML(nazwa);
            elementy.Dodaj(klasa);
            klasa.kontener = this;
            return klasa;
        }
        public AsocjacjaUML DodajAsocjacje()
        {
            AsocjacjaUML aso = new AsocjacjaUML();            
            Elementy.Dodaj(aso);
            return aso;
        }

        public AsocjacjaUML DodajAsocjacje(ElementUML element1, ElementUML element2)
        {
            AsocjacjaUML aso = new AsocjacjaUML();            
            aso.DodajZakonczenie(element1);
            aso.DodajZakonczenie(element2);
            Elementy.Dodaj(aso);
            return aso;
        }

        public PrymitywUML DodajPrymityw(String nazwa)
        {
            PrymitywUML prymityw = new PrymitywUML(nazwa);
            elementy.Dodaj(prymityw);
            return prymityw;
        }
        public AkcjaUML DodajAkcje()
        {
            AkcjaUML pu = new AkcjaUML();
            elementy.Dodaj(pu);
            return pu;
        }
        public InterfejsUML DodajInterfejs(String nazwa)
        {
            InterfejsUML i = new InterfejsUML(nazwa);
            elementy.Dodaj(i);
            i.kontener = this;
            return i;
        }
        
        public void DodajPrymitywyC()
        {
            elementy.Dodaj(new PrymitywUML("int"));
            elementy.Dodaj(new PrymitywUML("long"));
            elementy.Dodaj(new PrymitywUML("short"));
            elementy.Dodaj(new PrymitywUML("float"));
            elementy.Dodaj(new PrymitywUML("double"));
            elementy.Dodaj(new PrymitywUML("char"));
            elementy.Dodaj(new PrymitywUML("String"));
            elementy.Dodaj(new PrymitywUML("string"));
            elementy.Dodaj(new PrymitywUML("byte"));
            elementy.Dodaj(new PrymitywUML("short"));
        }

        void Wyswietl(KontenerUML k, int wciecie)
        {
            for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
            Console.Out.WriteLine("<Kontener: Klasa={0} Nazwa={1} >", k.GetType().ToString(), k.Nazwa);
            wciecie += 4;
            foreach (ElementUML el in k.elementy)
            {
                if (el.GetType().IsSubclassOf(typeof(KontenerUML)))
                {
                    Wyswietl((KontenerUML)el, wciecie);
                }
                else if (el.GetType() == typeof(KlasaUML) || el.GetType().IsSubclassOf(typeof(KlasaUML)))
                { 
                    KlasaUML kl = (KlasaUML)el;
                    for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                    Console.Out.WriteLine("<Klasa: Klasa={0} Nazwa={1} >", kl.GetType().ToString(), kl.Nazwa);
                    wciecie += 4;

                    foreach (OperacjaUML op in kl.operacje)
                    {
                        if (op.IloscAtrybutow > 0)
                        {
                            for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                            Console.Out.WriteLine("<Operacja: Klasa={0} Nazwa={1} ZwracanyTyp={2}>", op.GetType().ToString(), op.Nazwa, op.Typ);
                            wciecie += 4;
                            foreach (AtrybutUML atr in op.atrybuty)
                            {
                                for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                                Console.Out.WriteLine("<Atrybut: Klasa={0} Nazwa={1}\\>", atr.GetType().ToString(), atr.Nazwa);
                            }
                            wciecie -= 4;
                            for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                            Console.Out.WriteLine("</Operacja>");
                        }
                        else
                        {
                            for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                            Console.Out.WriteLine("<Operacja: Klasa={0} Nazwa={1} ZwracanyTyp={2}\\>", op.GetType().ToString(), op.Nazwa, op.Typ.Nazwa);
                        }
                    }
                    if (kl.atrybuty.Count > 0)
                    foreach (AtrybutUML atr in kl.atrybuty)
                    {
                        for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                        Console.Out.WriteLine("<Atrybut: Klasa={0} Nazwa={1}\\>", atr.GetType().ToString(), atr.Nazwa);
                    }
                    wciecie -= 4;
                    for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                    Console.Out.WriteLine("</Klasa>");
                }
            }
            wciecie -= 4;
            for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
            Console.Out.WriteLine("</Kontener>");
        }
        public void Wyswietl()
        {
            Console.Out.WriteLine("<Kontener: Klasa={0} Nazwa={1} >", this.GetType().ToString(), this.Nazwa);
            foreach (ElementUML el in elementy)
            {
                if (el.GetType().IsSubclassOf(typeof(KontenerUML)))
                {                    
                    Wyswietl((KontenerUML)el, 4);                  
                }
                else if (el.GetType().IsSubclassOf(typeof(KlasaUML)))
                {
                    int wciecie = 4;

                    KlasaUML kl = (KlasaUML)el;
                    for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                    Console.Out.WriteLine("<Klasa: Klasa={0} Nazwa={1} >", kl.GetType().ToString(), kl.Nazwa);
                    wciecie += 4;
                    
                    foreach (OperacjaUML op in kl.operacje)
                    {
                        if (op.IloscAtrybutow > 0)
                        {
                            for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                            Console.Out.WriteLine("<Operacja: Klasa={0} Nazwa={1} ZwracanyTyp={2}>", op.GetType().ToString(), op.Nazwa, op.Typ.Nazwa);
                            wciecie += 4;
                            foreach (AtrybutUML atr in op.atrybuty)
                            {
                                for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                                Console.Out.WriteLine("<Atrybut: Klasa={0} Nazwa={1}\\>", atr.GetType().ToString(), atr.Nazwa);
                            }
                            wciecie -= 4;
                            for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                            Console.Out.WriteLine("</Operacja>");
                        }
                        else
                        {
                            for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                            Console.Out.WriteLine("<Operacja: Klasa={0} Nazwa={1} ZwracanyTyp={2}\\>", op.GetType().ToString(), op.Nazwa, op.Typ);
                        }
                    }
                    foreach (AtrybutUML atr in kl.atrybuty)
                    {
                        for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                        Console.Out.WriteLine("<Atrybut: Klasa={0} Nazwa={1}\\>", atr.GetType().ToString(), atr.Nazwa);
                    }
                    wciecie -= 4;
                    for (int i = 0; i < wciecie; i++) Console.Out.Write(' ');
                    Console.Out.WriteLine("</Klasa>");
                }
            }
            Console.Out.WriteLine("</Kontener>");
        }
        public void UsunElementZModelu(ElementUML elementUML)
        {            
            List<iDiagram> diagramy = new List<iDiagram>();
            foreach (iDiagram diag in elementUML.diagramy)
            {
                diagramy.Add(diag);
            }

            foreach (iDiagram diag in diagramy)
            {
                iElementNaDiagramie el = diag.GetElementNaDiagramie(elementUML);
                diag.UsunElementZDiagramu(el);
            }
            this.elementy.Usun(elementUML);
        }
    }
}